#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import threading
import time

from pydbus import SessionBus
from gi.repository import GLib

from utils import tp_logging
from utils import tp_exceptions

import lyrics_parser
import lyrics_sync

logger = tp_logging.get_logger('media_player_manager')

bus = SessionBus()

dbus = bus.get('.DBus')


class MediaPlayerManager(object):

    def __init__(self):
        self.media_player_info = dict()
        self.verify_changes_on_media_player()

    def get_mediaplayer2_object(self):
        """Finds compatible media players accesible via D-Bus.

        Returns:
            DBUS.<CompositeObject>: Only compatible player running.
        """


        players_paths = list()

        for player_path in dbus.ListNames():
            if 'org.mpris.MediaPlayer' in player_path:
                players_paths.append(player_path)

        if len(players_paths) > 1:
            raise tp_exceptions.MoreThanOnePlayerRunning()

        player = bus.get(players_paths[0], '/org/mpris/MediaPlayer2')

        return player

    def watch_media_player_changes(self):
        """Watches for status changes on the media player."""

        player = self.get_mediaplayer2_object()

        player.PropertiesChanged.connect(self.verify_changes_on_media_player)

        GLib.MainLoop().run()

    def verify_changes_on_media_player(self, *args):
        """Verifies changes reported.

        Whenever a different song is selected, the respective .lrc file should
        be opened or a new one created.

        Args:
            *args:
        """

        metadata = self.get_mediaplayer2_object().Metadata

        title = metadata['xesam:title']
        artist = metadata['xesam:artist']

        same_song = True

        if title != self.media_player_info.get('title', ''):
            self.media_player_info['title'] = title
            same_song = False

        if artist != self.media_player_info.get('artist', ''):
            self.media_player_info['artist'] = artist
            same_song = False

        if not same_song:
            sync = lyrics_sync.LyricsSync(
                title=title, artist=artist, length=0)
            sync.create_lrc_file()

    def watch_playback_position(self):
        """Watches current position of the song execution.

        Dictates which lyrics piece should be displayed based on the position
        informed by the media player. Sleeping is needed to control CPU
        consumption.
        """

        player = self.get_mediaplayer2_object()

        position_microsec = player.Position

        micro_to_sec = lambda x: (x / (10 ** 6))

        # toply is getting the timing one second late
        last_sec = micro_to_sec(position_microsec) + 1

        while True:
            position_microsec = player.Position

            position_sec = micro_to_sec(position_microsec)

            time_since_last_loop_sec = position_sec - last_sec

            if 0 < time_since_last_loop_sec < .9:
                pass

            elif time_since_last_loop_sec > 0:
                print(position_sec)
                last_sec = position_sec

            else:
                last_sec = position_sec

            time.sleep(0.1)

if __name__ == '__main__':
    media_player_manager = MediaPlayerManager()

    watchers = [
        media_player_manager.watch_media_player_changes,
        media_player_manager.watch_playback_position]

    threads = []

    for watcher in watchers:
        watcher_thread = threading.Thread(target=watcher)
        threads.append(watcher_thread)
        watcher_thread.start()

